package com.hb.trade.server.center.au.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hb.core.pojo.UserConfig;
import com.hb.core.pojo.center.au.dto.OrgDTO;
import com.hb.core.pojo.center.au.dto.OrgExtDTO;
import com.hb.core.pojo.center.au.dto.UserDTO;
import com.hb.core.pojo.center.au.dto.ZappUserDTO;
import com.hb.core.pojo.center.au.entity.*;
import com.hb.core.pojo.center.sys.dto.CascadeQueryDTO;
import com.hb.core.pojo.center.sys.entity.DistrictInfo;
import com.hb.core.pojo.enums.RoleSignEnum;
import com.hb.core.pojo.enums.RoleTypeEnum;
import com.hb.core.pojo.parent.MPBaseController;
import com.hb.core.pojo.parent.MPCommonEntity;
import com.hb.core.pojo.parent.PageResult;
import com.hb.trade.server.center.au.manager.OrgManager;
import com.hb.trade.server.center.au.service.*;
import com.hb.trade.server.center.sys.service.DicCodeService;
import com.hb.trade.server.center.sys.service.DistrictInfoService;
import lombok.extern.slf4j.Slf4j;
import org.fzzn.core.model.enums.LogicEnum;
import org.fzzn.core.model.enums.MsgEnum;
import org.fzzn.core.model.enums.UserTypeEnum;
import org.fzzn.core.model.msg.Message;
import org.fzzn.core.util.Enums;
import org.fzzn.core.util.MsgUtil;
import org.fzzn.core.util.ResultUtil;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

/**
 * 组织架构信息表 前端控制器
 *
 * @author zhaojk
 * @since 2021-11-29
 */
@Slf4j
@RestController
public class OrgController extends MPBaseController<Org, OrgService> {

    protected final UserService userService;
    protected final RoleService roleService;
    protected final OrgDeptService deptService;
    protected final DistrictInfoService districtInfoService;
    protected final OrgExtService orgExtService;
    protected final OrgSupplyService orgSupplyService;
    protected final DicCodeService dicCodeService;

    public OrgController(OrgService service,
                         UserService userService,
                         RoleService roleService, OrgDeptService deptService,
                         DistrictInfoService districtInfoService,
                         OrgExtService orgExtService,
                         OrgSupplyService orgSupplyService,
                         DicCodeService dicCodeService) {
        super(service);
        this.userService = userService;
        this.roleService = roleService;
        this.deptService = deptService;
        this.districtInfoService = districtInfoService;
        this.orgExtService = orgExtService;
        this.orgSupplyService = orgSupplyService;
        this.dicCodeService = dicCodeService;
    }

    /**
     * 获取指定用户所在的企业信息
     *
     * @param username 参数支持的业务数据类型: 企业ID, 用户ID, 登录用户名
     * @return
     */
    @PostMapping("/org/getOrgByUsername")
    public Message<Org> getOrgByUsername(@RequestParam("username") Serializable username) {
        if (username == null) {
            return MsgUtil.msg(MsgEnum.INCORRECT_PARAM);
        }

        // 企业信息查询条件
        QueryWrapper<Org> wrapperOrg = Org.wrapper(
                "id", "tenant_id", "parent_id", "org_name",
                "credit_code", "industry_id", "province_id", "city_id", "area_id",
                "contact_phone", "contact_address", "contact_name", "email");

        // 查询用户信息
        QueryWrapper<User> wrapper = UserDTO.wrapper("org_id");
        wrapper.eq("username", username);
        wrapper.last("limit 1");

        // 临时用户对象
        User tempUser = userService.getOne(wrapper);

        if (tempUser != null) {
            wrapperOrg.eq("id", tempUser.getOrgId());
            return MsgUtil.success(service.getOne(wrapperOrg));
        }

        tempUser = userService.getById(username);

        if (tempUser != null) {
            wrapperOrg.eq("id", tempUser.getOrgId());
            return MsgUtil.success(service.getOne(wrapperOrg));
        }

        wrapperOrg.eq("id", username);
        Org org = service.getOne(wrapperOrg);
        if (org == null) {
            return MsgUtil.msg(MsgEnum.NULL_RESULT);
        }
        return MsgUtil.success(org);
    }

    /**
     * 获取指定用户所在的企业信息
     *
     * @param orgDTO 企业名称(模糊搜索), 企业信用代码(精确查询)
     * @return
     */
    @PostMapping("/org/pageOrgs")
    public Message<PageResult<OrgDTO>> pageOrgs(@RequestBody OrgDTO orgDTO) {
//        // 查询用户信息
//        QueryWrapper<Org> wrapper = OrgDTO.wrapper();
//        wrapper.like(StrUtil.isNotEmpty(orgDTO.getOrgName()), "org_name", orgDTO.getOrgName())
//                .eq(StrUtil.isNotEmpty(orgDTO.getCreditCode()), "credit_code", orgDTO.getCreditCode());
//
//        // 判断是否展示当前登录企业
//        if (null != orgDTO && null != orgDTO.getShowLoginUser() && orgDTO.getShowLoginUser() == 1) {
//            wrapper.ne(null != orgDTO.getOrgId(), "id", orgDTO.getOrgId());
//        }
//        Page<Org> pages = page(wrapper, orgDTO.pages());
        Page<Org> pages = service.pageTenderOrg(orgDTO);

        // 查询企业的创建人
        for (Org orgInfo : pages.getRecords()) {
            QueryWrapper<User> userQueryWrapper = OrgSupply.wrapper();
            userQueryWrapper.eq("org_id", orgInfo.getId()).orderByAsc("create_time");

            // 获取当前企业下全部的人员  获取最早的创建人
            List<User> userList = userService.list(userQueryWrapper);
            if (!userList.isEmpty()) {
                orgInfo.setContactName(userList.get(0).getFullName());
                orgInfo.setContactPhone(userList.get(0).getPhone());
            }
        }


        PageResult<Org> orgPageResult = PageResult.get(pages);
        PageResult<OrgDTO> orgDTOPageResult = orgPageResult.transferTo(OrgDTO.class);
        List<OrgDTO> records = orgDTOPageResult.getRecords();
        if (records.size() > 0) {
            for (OrgDTO orgDTO1 : records) {
                orgDTO1.setOrgId(orgDTO1.getId());
            }
        }
        return MsgUtil.success(orgDTOPageResult);
    }

    /**
     * @param orgDTO:
     * @Description: 完善企业信息
     * @Author: zhongdl
     * @Date:2022/1/15 15:31
     * @return: {@link Message< OrgDTO> }
     **/
    @PostMapping("/org/perfectInformation")
    public Message<Boolean> perfectInformation(@RequestBody OrgDTO orgDTO) {
        orgDTO.setParentId(null);
        boolean flag = service.updateById(orgDTO);
        //企业扩展信息
        OrgExtDTO orgExtDTO = orgDTO.getOrgExt();
        //完善企业扩展信息
        boolean orgExtFlag;
        //查询一下扩展信息是否存在
        OrgExt orgExt = orgExtService.getOrgExtByOrgId(orgDTO.getId());

        if (orgExt != null && orgExt.getId() != null) {
            //更新扩展信息
            orgExtDTO.setId(orgExt.getId());
            orgExtFlag = orgExtService.updateById(orgExtDTO);
        } else {
            //新增扩展信息
            orgExtDTO.setOrgId(orgDTO.getId());
            orgExtFlag = orgExtService.saveOrgExtDTO(orgExtDTO);
        }
        return MsgUtil.success(flag && orgExtFlag);
    }

    /**
     * @param orgId:
     * @Description: 根据企业id查询企业信息
     * @Author: zhongdl
     * @Date:2022/1/15 15:31
     * @return: {@link Message< OrgDTO> }
     **/
    @PostMapping("/org/getOrgById")
    public Message<OrgDTO> getOrgById(@RequestParam Long orgId) {
        /*QueryWrapper<Org> orgWrapper = Org.wrapper("id", "tenant_id", "parent_id", "org_name",
                "credit_code", "industry_id", "`province_id`", "city_id", "contact_phone", "contact_address", "contact_name",
                "org_manager", "email", "area_id", "note", "reason", "level", "legal_name", "certificate_number", "certificate_type", "audit_status");*/
        QueryWrapper<Org> orgWrapper = Org.wrapper();
        orgWrapper.eq("id", orgId);
        Org org = service.getOne(orgWrapper, false);
        if (org == null) {
            return MsgUtil.msg(MsgEnum.NULL_RESULT);
        }
        OrgDTO orgDTO = org.to(OrgDTO.class);
        //查询企业扩展信息
        OrgExt orgExt = orgExtService.getOrgExtByOrgId(orgId);
        if (orgExt != null) {
            orgDTO.setOrgExt(orgExt.to(OrgExtDTO.class));
        }
        return MsgUtil.success(orgDTO);

    }

    /**
     * 查询指定用户所在的企业以及子公司列表
     * 超级管理员将返回全部企业数据
     *
     * @param user
     * @return
     */
    @PostMapping("/org/listByUserInfo")
    public Message<List<Org>> listByUserInfo(@RequestBody User user) {
        Long userId = user.getId();
        User orgUser = userService.getById(userId);
        if (orgUser == null) {
            return MsgUtil.fail("用户信息不存在");
        }

        QueryWrapper<Org> wrapper = Org.wrapper();
        wrapper.orderByAsc("level");

        // 超级管理员返回全部企业信息
        if (Enums.equals(UserTypeEnum.SUPER_ADMIN, orgUser.getUserType())) {
            List<Org> list = service.list(wrapper);
            return MsgUtil.success(list);
        }

        Long orgId = orgUser.getOrgId();

        // 企业管理员显示当前所在企业下的子公司
        if (Enums.equals(UserTypeEnum.ORG_ADMIN, orgUser.getUserType())) {
            CascadeQueryDTO cascadeQuery = new CascadeQueryDTO(orgId, "au_org");
            List<Long> orgIds = dicCodeService.getChildList(cascadeQuery);
            wrapper.in("id", orgIds);
            List<Org> list = service.list(wrapper);
            return MsgUtil.success(list);
        }

        // 普通用户只配看到当前所在企业
        Org org = service.getById(orgId);
        return MsgUtil.success(CollUtil.list(false, org));
    }

    /**
     * @param orgId:
     * @Description: 查询当前父企业和子企业
     * @Author: zhongdl
     * @Date:2022/1/20 14:43
     * @return: {@link Message< List< Org>> }
     * @deprecated 方法局限性太大
     **/
    @Deprecated
    @PostMapping("/org/listParentAndSon")
    public Message<List<OrgDTO>> listParentAndSon(@RequestParam Long orgId) {

        List<Org> parentList = service.listParent(orgId);
        List<Org> sonList = service.listSon(orgId);

        Collection<OrgDTO> orgs = CollUtil.addAll(OrgManager.changeOrgDTOList(parentList, true),
                OrgManager.changeOrgDTOList(sonList, false));
        return MsgUtil.msg(CollUtil.list(false, orgs));

    }

    /**
     * @param orgId:
     * @Description: 查询当前企业的父企业(不包含自己)
     * @Author: zhongdl
     * @Date:2022/1/20 8:59
     * @return: {@link Message< OrgDTO> }
     **/
    @PostMapping("/org/listParent")
    public Message<List<Org>> listParent(@RequestParam Long orgId) {
        List<Org> parentList = service.listParent(orgId);
        return MsgUtil.msg(parentList);

    }

    /**
     * @param orgId:
     * @Description: 查询当前子企业(包含自己)
     * @Author: zhongdl
     * @Date:2022/1/20 8:59
     * @return: {@link Message< OrgDTO> }
     **/
    @PostMapping("/org/listSon")
    public Message<List<Org>> listSon(@RequestParam Long orgId) {
        List<Org> sonList = service.listSon(orgId);
        return MsgUtil.success(sonList);

    }

    /**
     * 查询指定企业的供应商库
     *
     * @param org#id      企业ID
     * @param org#orgName 企业名称, 查询条件
     * @author zhaojk
     */
    @PostMapping("/org/tender/history")
    public Message<PageResult<OrgDTO>> tenderHistory(@RequestBody OrgDTO org) {
        Page<OrgDTO> orgDTOPage = orgSupplyService.pageSupply(org);
        return MsgUtil.success(PageResult.get(orgDTOPage));

    }

    /**
     * 保存供应商信息至供应商库
     *
     * @param bidOrgId  招标人企业ID
     * @param tendOrgId 投标人企业ID
     * @author zhaojk
     */
    @PostMapping("/org/tender/saveSupply")
    public Message<Boolean> tenderSaveSupply(Long bidOrgId, Long tendOrgId) {
        if (bidOrgId == null || tendOrgId == null) {
            return MsgUtil.msg(MsgEnum.INCORRECT_PARAM);
        }

        QueryWrapper<OrgSupply> wrapper = OrgSupply.wrapper();
        wrapper.eq("bid_org_id", bidOrgId).eq("tend_org_id", tendOrgId).last("limit 1");
        OrgSupply orgSupply = orgSupplyService.getOne(wrapper);
        if (orgSupply == null) {
            OrgSupply supply = new OrgSupply();
            supply.setBidOrgId(bidOrgId);
            supply.setTendOrgId(tendOrgId);
            supply.buildBaseData(1);
            orgSupplyService.save(supply);
        }
        return MsgUtil.msg(true);
    }


    /**
     * @param orgDTO:
     * @Description: 保存企业
     * @Author: zhongdl
     * @Date:2022/2/11 10:59
     * @return: {@link Message< OrgDTO> }
     **/
    @PostMapping("/org/saveOrg")
    public Message<OrgDTO> saveOrg(@RequestBody OrgDTO orgDTO) {
        boolean result;
        if (orgDTO.getId() == null) {
            // 验证企业名称是否存在
            OrgManager manager = orgDTO.to(OrgManager.class);
            String msg = manager.checkName(null);
            if (StrUtil.isNotEmpty(msg)) {
                return MsgUtil.fail(msg);
            }
            manager.buildBaseData(1);

            //复制父级公司默认信息
            manager.initOrgInfo();
            result = service.save(manager);
            //添加扩展信息
            if (manager.getOrgExt() != null) {
                orgExtService.saveOrUpdate(manager.getOrgExt());
            }
            //
            // 添加默认企业信息
            manager.initRoleInfo(orgDTO.getRoleSign());
            manager.to(orgDTO);
        } else {
            orgDTO.buildBaseData(2);
            result = service.updateById(orgDTO);
        }
        if (!result) {
            log.warn("新增分公司失败");
        }
        return MsgUtil.success(orgDTO);
    }

    /**
     * 删除企业
     *
     * @param orgDTO
     * @return
     */
    @PostMapping("/org/removeOrgById")
    public Message<Boolean> removeOrgById(@RequestBody OrgDTO orgDTO) {
        Long orgId = orgDTO.getId();

        QueryWrapper<User> wrapper = User.wrapper();
        wrapper.lambda().eq(User::getOrgId, orgId);

        long count = userService.count(wrapper);
        if (count > 0) {
            return MsgUtil.fail("公司下有账号，请先移除账号");
        }

        boolean markDeleteById = markDeleteById(orgId);
        return MsgUtil.success(markDeleteById);
    }

    /**
     * 获取指定企业下的分公司管理员
     *
     * @param orgId
     * @return
     */
    @PostMapping("/org/getBranchManager")
    public Message<List<UserDTO>> getBranchManager(Long orgId, Long userId) {
        if (orgId == null) {
            return MsgUtil.msg(MsgEnum.INCORRECT_PARAM);
        }
        List<UserDTO> users = service.getUser(orgId, RoleTypeEnum.BRANCH_COMPANY_MANAGER);
        if (userId != null) {
            CollUtil.filter(users, item -> !(item.getId().equals(userId)));
        }
        return MsgUtil.msg(users);
    }

    /**
     * 查询总公司
     *
     * @param orgId
     * @return
     */
    @PostMapping("/org/getHeadOffice")
    public Message<OrgDTO> getHeadOffice(@RequestBody Long orgId) {
        if (orgId == null) {
            return MsgUtil.msg(MsgEnum.INCORRECT_PARAM);
        }
        OrgDTO orgDTO = service.getHeadOffice(orgId);
        return MsgUtil.success(orgDTO);
    }

    /**
     * 总公司在授予分公司权限后的处理操作
     * 当授予"分公司权限"时, 给总公司添加"分公司管理员"的角色
     * 当取消"分公司权限"时, 给总公司移除"分公司管理员"的角色, 但是已经创建了分公司的企业, 不能移除
     *
     * @param orgId
     * @param userConfig
     * @return
     */
    @PostMapping("/org/handleBranchManager")
    public Message<Boolean> handleBranchManager(@RequestParam Long orgId, @RequestBody UserConfig userConfig, @RequestParam Integer roleSign) {
        if (orgId == null) {
            return MsgUtil.msg(MsgEnum.INCORRECT_PARAM);
        }
        Integer canCreateBranchCompany = userConfig.getCanCreateBranchCompany();
        LogicEnum logicEnum = Enums.of(LogicEnum.class, canCreateBranchCompany);

        // 添加分公司管理员
        if (logicEnum == LogicEnum.YES) {
            roleService.initData(orgId, canCreateBranchCompany, 1, RoleSignEnum.AGENCY.getCode());
        } else {
            // 如果是取消分公司权限, 给总公司移除"分公司管理员"的角色, 但是已经创建了分公司的企业, 不能移除
            QueryWrapper<Org> wrapper = Org.wrapper();
            wrapper.eq("parent_id", orgId);
            long count = service.count(wrapper);
            // 没有创建过分公司
            if (count == 0) {
                QueryWrapper<Role> roleWrapper = Role.wrapper();
                roleWrapper.eq("org_id", orgId).eq("role_type", RoleTypeEnum.BRANCH_COMPANY_MANAGER.getCode());
                roleService.remove(roleWrapper);
            }
        }
        return MsgUtil.msg(0);
    }


    /**
     * 企业是否认证
     *
     * @param orgDTO
     * @return
     */
    @PostMapping("/org/orgConfirm")
    public Message orgConfirm(@RequestBody OrgDTO orgDTO) {
        boolean result = service.orgConfirm(orgDTO);
        return MsgUtil.msg(result);
    }

    @PostMapping("/org/getOrgByOrgName")
    public Message<Org> getOrgByOrgName(@RequestBody String orgName) {
        LambdaQueryWrapper<Org> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Org::getOrgName, orgName);
        wrapper.last("limit 1");
        Org org = service.getOne(wrapper);
        return MsgUtil.msg(org);
    }

    /**
     * 扫码加密时候判断章的信息与账号企业信息是否匹配
     * @param orgDTO
     * @return
     * @author ljs
     * @date 2022年5月27日
     */
    @PostMapping("/org/checkOrgMsgByZapp")
    public Message<Boolean> checkOrgMsgByZapp(@RequestBody OrgDTO orgDTO){
        LambdaQueryWrapper<Org> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Org::getId, orgDTO.getOrgId());
        wrapper.last("limit 1");
        Org org = service.getOne(wrapper);
        if (org == null) {
            return MsgUtil.fail("企业不存在");
        }
        if (!orgDTO.getParentId().equals(0L)) {
            OrgDTO orgDTO1 = service.getHeadOffice(org.getId());
            org = orgDTO1.to(Org.class);
        }
        if (orgDTO.getOrgName().equals(org.getOrgName()) && orgDTO.getCreditCode().equals(org.getCreditCode())){
            return MsgUtil.success(true);
        }
        return MsgUtil.fail("中招企业信息与账号企业信息不符！");
    }
}
